package com.example.springcloud.account.service.tcc;

import com.example.springcloud.account.mapper.AccountMapper;
import io.seata.core.context.RootContext;
import io.seata.rm.tcc.api.BusinessActionContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;

@Slf4j
@Service
public class AccountTCCServiceImpl implements AccountTCCService {

    @Autowired
    private AccountMapper accountMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void tryDeduct(Long userId, BigDecimal money) {
        log.info("账户服务 TCC Try：冻结余额");
        log.info("全局事务 XID: {}", RootContext.getXID());
        log.info("用户ID: {}, 冻结金额: {}", userId, money);
        
        int result = accountMapper.freeze(userId, money);
        if (result == 0) {
            throw new RuntimeException("余额不足，无法冻结");
        }
        
        log.info("余额冻结成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean confirm(BusinessActionContext context) {
        log.info("账户服务 TCC Confirm：确认扣减余额");
        log.info("全局事务 XID: {}", context.getXid());
        
        Long userId = Long.valueOf(context.getActionContext("userId").toString());
        BigDecimal money = new BigDecimal(context.getActionContext("money").toString());
        
        int result = accountMapper.confirmDeduct(userId, money);
        log.info("余额确认扣减成功");
        return result > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cancel(BusinessActionContext context) {
        log.info("账户服务 TCC Cancel：释放冻结的余额");
        log.info("全局事务 XID: {}", context.getXid());
        
        Long userId = Long.valueOf(context.getActionContext("userId").toString());
        BigDecimal money = new BigDecimal(context.getActionContext("money").toString());
        
        int result = accountMapper.cancelDeduct(userId, money);
        log.info("余额释放成功");
        return result > 0;
    }
}
